const Koa = require("koa");
const path = require("path");
const { sep } = path;
const env = require("./env");
const middlewareLoader = require("./loader/middleware");
const routerSchemaLoader = require("./loader/router-schema");
const controllerLoader = require("./loader/controller");
const serviceLoader = require("./loader/service");
const config = require("./loader/config");
const extendLoader = require("./loader/extend");
const routerLoader = require("./loader/router");

/**
 * Elpis核心模块
 */
module.exports = {
  /**
   * 启动Elpis核心模块
   * @param {*} options 启动选项
   */
  start: (options = {}) => {
    const app = new Koa();

    app.options = options;

    /**
     * Elpis核心模块运行时目录
     */
    app.baseDir = process.cwd();
    app.bisinessPath = path.resolve(app.baseDir, `.${sep}app`);

    /**
     * Elpis核心模块环境变量
     */
    app.env = env(app);
    console.log(`-- [start] env ${app.env.get()} --`);

    // 加载中间件
    middlewareLoader(app);
    console.log(`-- [start] middleware loaded --`);

    // 加载路由配置
    routerSchemaLoader(app);
    console.log(`-- [start] router schema loaded --`);

    // 加载控制器
    controllerLoader(app);
    console.log(`-- [start] controller loaded --`);

    // 加载服务
    serviceLoader(app);
    console.log(`-- [start] service loaded --`);

    // 加载配置
    config(app);
    console.log(`-- [start] config loaded --`);

    // 加载扩展
    extendLoader(app);
    console.log(`-- [start] extend loaded --`);

    // 加载应用中间件
    try {
      require(`${app.bisinessPath}${sep}middleware.js`)(app);
      console.log("-- [start] appMiddleware loaded");
    } catch (error) {
      console.log(error);
      console.log(`-- [error] there is no global middleware --`);
    }

    // 加载路由
    routerLoader(app);
    console.log(`-- [start] router loaded --`);

    const port = process.env.port || 8080;
    const host = process.env.IP || "0.0.0.0";
    // 定义路由
    app.use(async (ctx) => {
      ctx.body = "Hello, Koa!";
    });

    // 启动应用
    app.listen(port, host, () => {
      console.log(`Koa server is running on http://${host}:${port}`);
    });
    return app;
  },
};
